﻿using Bandit.Helpers;
using Bandit.UI.MVVM;
using ETC.DLEDLightingSystemPlus.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace ETC.DLEDLightingSystemPlus.ViewModels
{
    public class MainViewModel : NotifyObject
    {
        public delegate void LoginHandler(bool isLogin);
        public event LoginHandler OnLoginChanged;

        public delegate void TestStationsChangedHandler();
        public event TestStationsChangedHandler OnTestStationsChanged;

        #region TestInfo
        /// <summary>
        /// Test Information
        /// </summary>
        public TestInfo TestInfo { get; private set; }
        #endregion

        private string _TestProjectStationName;

        public string TestProjectStationName
        {
            get { return _TestProjectStationName; }
            set
            {
                _TestProjectStationName = value;
                OnPropertyChanged(nameof(TestProjectStationName));
            }
        }

        #region 测试信息

        public System.Collections.ObjectModel.ObservableCollection<TestStation> TestStations { get; set; }

        public int StationCount
        {
            
            get
            {
                return this.TestStations.Count;
            }

        }

        public int ColumnCount
        {
            get
            {
                if (this.StationCount > App.SettingViewModel.Setting.MaxColumnCount)
                {
                    return App.SettingViewModel.Setting.MaxColumnCount;
                }

                return this.StationCount;
            }
        }

        public int RowCount
        {
            get
            {
                if (this.StationCount > App.SettingViewModel.Setting.MaxColumnCount)
                {
                    return (int)Math.Ceiling((double)this.StationCount / this.ColumnCount);
                }

                return 1;
            }
        }

        #endregion

        #region PLC 属性
        private bool _IsDebug;
        public bool IsDebug
        {
            get
            {
                return _IsDebug;
            }
            set
            {
                _IsDebug = value;
                OnPropertyChanged(nameof(IsDebug));
            }
        }

        private string _PLC_IPName;
        public string PLC_IPName
        {
            get
            {
                return _PLC_IPName;
            }
            set
            {
                _PLC_IPName = value;
                OnPropertyChanged(nameof(PLC_IPName));
                Bandit.Helpers.ConfigHelper.SetValue("PLC_IPName", _PLC_IPName);

            }
        }
        private int _PLC_PortName;
        public int PLC_PortName
        {
            get
            {
                return _PLC_PortName;
            }
            set
            {
                _PLC_PortName = value;
                OnPropertyChanged(nameof(PLC_PortName));
                Bandit.Helpers.ConfigHelper.SetValue("PLC_PortName", _PLC_PortName);

            }
        }
        private bool _IsPLCConnect = false;
        public bool IsPLCConnect
        {
            get
            {
                return _IsPLCConnect;
            }
            set
            {
                _IsPLCConnect = value;
                OnPropertyChanged(nameof(IsPLCConnect));
                if (value) 
                {
                    PLCStatus.Update("PLC is connected", MyBrushes.Green);
                }
                else
                {
                    PLCStatus.Update("PLC is not connected", MyBrushes.Red);
                }
                IsPLCButtonEnable = !_IsPLCConnect;
            }
        }
        private bool _IsPLCButtonEnable = true;
        public bool IsPLCButtonEnable
        {
            get
            {
                return _IsPLCButtonEnable;
            }
            set
            {
                _IsPLCButtonEnable = value;
                OnPropertyChanged(nameof(IsPLCButtonEnable));
            }
        }

        private string _ReadAddressValue;
        public string ReadAddressValue
        {
            get { return _ReadAddressValue; }
            set
            {
                _ReadAddressValue = value;
                OnPropertyChanged(nameof(ReadAddressValue));
            }
        }

        private string _ReadAOIAddress1 = "D4500";
        public string ReadAOIAddress1
        {
            get
            {
                return _ReadAOIAddress1;
            }
            set
            {
                _ReadAOIAddress1 = value;
                OnPropertyChanged(nameof(ReadAOIAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("ReadAOIAddress1", ReadAOIAddress1);
            }
        }

        private string _WriteAOIAddress1;
        public string WriteAOIAddress1
        {
            get
            {
                return _WriteAOIAddress1;
            }
            set
            {
                _WriteAOIAddress1 = value;
                OnPropertyChanged(nameof(WriteAOIAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("WriteAOIAddress1", WriteAOIAddress1);
            }
        }
        private string _ReadAOIAddress2;
        public string ReadAOIAddress2
        {
            get
            {
                return _ReadAOIAddress2;
            }
            set
            {
                _ReadAOIAddress2 = value;
                OnPropertyChanged(nameof(ReadAOIAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("ReadAOIAddress2", ReadAOIAddress2);
            }
        }

        private string _WriteAOIAddress2;
        public string WriteAOIAddress2
        {
            get
            {
                return _WriteAOIAddress2;
            }
            set
            {
                _WriteAOIAddress2 = value;
                OnPropertyChanged(nameof(WriteAOIAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("WriteAOIAddress2", WriteAOIAddress2);
            }
        }

        private string _ReadACAddress1;
        public string ReadACAddress1
        {
            get
            {
                return _ReadACAddress1;
            }
            set
            {
                _ReadACAddress1 = value;
                OnPropertyChanged(nameof(ReadACAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("ReadACAddress1", ReadACAddress1);
            }
        }

        private string _WriteACAddress1;
        public string WriteACAddress1
        {
            get
            {
                return _WriteACAddress1;
            }
            set
            {
                _WriteACAddress1 = value;
                OnPropertyChanged(nameof(WriteACAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("WriteACAddress1", WriteACAddress1);
            }
        }
        private string _ReadACAddress2;
        public string ReadACAddress2
        {
            get
            {
                return _ReadACAddress2;
            }
            set
            {
                _ReadACAddress2 = value;
                OnPropertyChanged(nameof(ReadACAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("ReadACAddress2", ReadACAddress2);
            }
        }

        private string _WriteACAddress2;
        public string WriteACAddress2
        {
            get
            {
                return _WriteACAddress2;
            }
            set
            {
                _WriteACAddress2 = value;
                OnPropertyChanged(nameof(WriteACAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("WriteACAddress2", WriteACAddress2);
            }
        }

        private string _ReadNTCAddress1;
        public string ReadNTCAddress1
        {
            get
            {
                return _ReadNTCAddress1;
            }
            set
            {
                _ReadNTCAddress1 = value;
                OnPropertyChanged(nameof(ReadNTCAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("ReadNTCAddress1", ReadNTCAddress1);
            }
        }

        private string _WriteNTCAddress1;
        public string WriteNTCAddress1
        {
            get
            {
                return _WriteNTCAddress1;
            }
            set
            {
                _WriteNTCAddress1 = value;
                OnPropertyChanged(nameof(WriteNTCAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("WriteNTCAddress1", WriteNTCAddress1);
            }
        }

        private string _WriteNTCPowerOffAddress1;
        public string WriteNTCPowerOffAddress1
        {
            get
            {
                return _WriteNTCPowerOffAddress1;
            }
            set
            {
                _WriteNTCPowerOffAddress1 = value;
                OnPropertyChanged(nameof(WriteNTCPowerOffAddress1));
                Bandit.Helpers.ConfigHelper.SetValue("WriteNTCPowerOffAddress1", WriteNTCPowerOffAddress1);
            }
        }
        private string _ReadNTCAddress2;
        public string ReadNTCAddress2
        {
            get
            {
                return _ReadNTCAddress2;
            }
            set
            {
                _ReadNTCAddress2 = value;
                OnPropertyChanged(nameof(ReadNTCAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("ReadNTCAddress2", ReadNTCAddress2);
            }
        }

        private string _WriteNTCAddress2;
        public string WriteNTCAddress2
        {
            get
            {
                return _WriteNTCAddress2;
            }
            set
            {
                _WriteNTCAddress2 = value;
                OnPropertyChanged(nameof(WriteNTCAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("WriteNTCAddress2", WriteNTCAddress2);
            }
        }

        private string _WriteNTCPowerOffAddress2;
        public string WriteNTCPowerOffAddress2
        {
            get
            {
                return _WriteNTCPowerOffAddress2;
            }
            set
            {
                _WriteNTCPowerOffAddress2 = value;
                OnPropertyChanged(nameof(WriteNTCPowerOffAddress2));
                Bandit.Helpers.ConfigHelper.SetValue("WriteNTCPowerOffAddress2", WriteNTCPowerOffAddress2);
            }
        }
        #endregion

        #region New Station
        private string _PortName;
        /// <summary>
        /// Selected PLC
        /// </summary>
        public string PortName
        {
            get { return _PortName; }
            set
            {
                _PortName = value;

                OnPropertyChanged("PortName");

            }
        }
        #endregion

        #region IsLogin
        private bool _IsLogin;
        /// <summary>
        /// 是否登录
        /// </summary>
        public bool IsLogin
        {
            get { return _IsLogin; }
            set
            {
                if (value != _IsLogin)
                {
                    _IsLogin = value;
                    OnPropertyChanged("IsLogin");
                    if (OnLoginChanged != null)
                    {
                        OnLoginChanged(value);
                    }
                }
            }
        }
        #endregion

        #region Setting
        /// <summary>
        /// Setting
        /// </summary>
        public Setting Setting { get { return App.SettingViewModel.Setting; } }
        #endregion

        #region IsEngineer
        private bool _IsEngineer;
        /// <summary>
        /// IsEngineer
        /// </summary>
        public bool IsEngineer
        {
            get { return _IsEngineer; }
            set
            {
                _IsEngineer = value;
                OnPropertyChanged("IsEngineer");
            }
        }
        #endregion

        #region OnClick
        /// <summary>
        /// Click Event
        /// </summary>
        public ICommand OnClick { get; set; }

        public ICommand OnPLCClick { get; set; }
        #endregion

        #region Status

        /// <summary>
        /// 状态
        /// </summary>
        public Status Status { get; set; }

        #endregion

        #region ScanStatus1

        /// <summary>
        /// Usb状态
        /// </summary>
        public Status ScanStatus1 { get; set; }

        #endregion

        #region ScanStatus2

        /// <summary>
        /// Usb状态
        /// </summary>
        public Status ScanStatus2 { get; set; }

        #endregion

        #region PLCStatus

        /// <summary>
        /// Usb状态
        /// </summary>
        public Status PLCStatus { get; set; }

        #endregion
        #region MESStatus

        /// <summary>
        /// MES状态
        /// </summary>
        public Status MESStatus { get; set; }

        #endregion

        #region EngineerMode
        private bool _EngineerMode;
        /// <summary>
        /// 启用为工程师模式
        /// </summary>
        public bool EngineerMode
        {
            get { return _EngineerMode; }
            set
            {
                _EngineerMode = value;
                OnPropertyChanged("EngineerMode");
            }
        }
        #endregion

        #region TetraModel

        private Tetra _TetraModel;
        public Tetra TetraModel
        {
            get { return _TetraModel; }
            set
            {
                _TetraModel = value;
                OnPropertyChanged("TetraModel");
            }
        }

        #endregion

        public Core.JsonConfig JsonConfig { get; set; }

        #region TetraTcgFileInfoList
        private ObservableCollection<TetraTcgFileInfo> _TetraTcgFileInfoList;

        public ObservableCollection<TetraTcgFileInfo> TetraTcgFileInfoList
        {
            get { return _TetraTcgFileInfoList; }
            set
            {
                _TetraTcgFileInfoList = value;
                OnPropertyChanged(nameof(TetraTcgFileInfoList));
            }
        }

        #endregion

        #region remoteConfigFileList
        private List<ConfigFileModel> _ConfigFileModels;

        public List<ConfigFileModel> ConfigFileModels
        {
            get { return _ConfigFileModels; }
            set
            {
                _ConfigFileModels = value;
                OnPropertyChanged(nameof(ConfigFileModels));
            }
        }
        #endregion

        #region remoteTestLogList
        private ObservableCollection<TetraTestLogModel> _RemoteTestLogModels;

        public ObservableCollection<TetraTestLogModel> RemoteTestLogModels
        {
            get { return _RemoteTestLogModels; }
            set
            {
                _RemoteTestLogModels = value;
                OnPropertyChanged(nameof(RemoteTestLogModels));
            }
        }
        #endregion

        #region ConfigFileModel
        private ConfigFileModel _ConfigFileModel;
        public ConfigFileModel ConfigFileModel
        {
            get { return _ConfigFileModel; }
            set
            {
                _ConfigFileModel = value;
                OnPropertyChanged("ConfigFileModel");
            }
        }
        #endregion

        #region TestLogFileModel
        private TetraTestLogModel _TestLogFileModel;
        public TetraTestLogModel TestLogFileModel
        {
            get { return _TestLogFileModel; }
            set
            {
                _TestLogFileModel = value;
                OnPropertyChanged("TestLogFileModel");
            }
        }
        #endregion

        #region Station Set
        public TestStation GetStation(int number)
        {
            return TestStations.FirstOrDefault(s => s.StationInfo.Number == number);
        }

        public void FireUIChanged()
        {
            if (OnTestStationsChanged != null)
            {
                OnTestStationsChanged();
            }
            OnPropertyChanged("StationCount");
            OnPropertyChanged("RowCount");
            OnPropertyChanged("ColumnCount");
        }

        public void AddStation(TestStation testStation)
        {
            this.TestStations.Add(testStation);
            this.RefreshStations();
        }

        public void RemoveStation(TestStation testStation, bool isRefresh)
        {
            this.TestStations.Remove(testStation);
            if (isRefresh)
            {
                this.RefreshStations();
            }
        }


        public void RefreshStations()
        {
            this.FireUIChanged();
            this.SaveStations();
        }

        public void SaveStations()
        {
            var stationInfos = TestStations.Select(s => s.StationInfo).OrderBy(s => s.Index).ToArray();
            ConfigHelper.XmlFileSerialize(stationInfos, App.GetFilePathOfTestStationConfig());
        }
        public void LoadStations()
        {
            if (System.IO.File.Exists(App.GetFilePathOfTestStationConfig()))
            {
                TestStations.Clear();

                StationInfo[] stationInfos = ConfigHelper.XmlFileDeserialize<StationInfo[]>(App.GetFilePathOfTestStationConfig());

                foreach (var stationInfo in stationInfos)
                {
                    TestStations.Add(new TestStation(stationInfo));
                }
            }

            if (this.StationCount == 0)
            {

                this.AddStation(new TestStation(new Models.StationInfo("Name1","COM99",1)));
                
            }

            this.TestProjectStationName = App.StationConfigName;

            //foreach (TestStation testStation in TestStations)
            //{
            //    if (testStation.ConfigInfo.TestConfig != null)
            //    {
            //        this.TestProjectStationName += "-" + testStation.ConfigInfo.TestConfig.TestCodeModels.First(s => s.TestModelCode == testStation.ConfigInfo.TestConfig.TestCommand.TestModelCode).Name;
            //    }
            //}

        }

        #endregion

        #region Constructors[构造函数]

        public MainViewModel()
        {
            this.TestInfo = new TestInfo();

            this.TestStations = new System.Collections.ObjectModel.ObservableCollection<TestStation>();

            this.TetraTcgFileInfoList = new ObservableCollection<TetraTcgFileInfo>();

            this.Status = new Status(App.GetString("Ready"), MyBrushes.White);

            this.PLC_IPName = ConfigHelper.GetVauleToString("PLC_IPName");
            this.PLC_PortName =int.Parse(ConfigHelper.GetVauleToString("PLC_PortName"));
            this.ReadAOIAddress1 = ConfigHelper.GetVauleToString("ReadAOIAddress1");
            this.ReadAOIAddress2 = ConfigHelper.GetVauleToString("ReadAOIAddress2");
            this.ReadACAddress1 =  ConfigHelper.GetVauleToString("ReadACAddress1");
            this.ReadACAddress2 =  ConfigHelper.GetVauleToString("ReadACAddress2");
            this.ReadNTCAddress1 = ConfigHelper.GetVauleToString("ReadNTCAddress1");
            this.ReadNTCAddress2 = ConfigHelper.GetVauleToString("ReadNTCAddress2");
            this.WriteAOIAddress1 = ConfigHelper.GetVauleToString("WriteAOIAddress1");
            this.WriteAOIAddress2 = ConfigHelper.GetVauleToString("WriteAOIAddress2");
            this.WriteACAddress1 =  ConfigHelper.GetVauleToString("WriteACAddress1");
            this.WriteACAddress2 =  ConfigHelper.GetVauleToString("WriteACAddress2");
            this.WriteNTCAddress1 = ConfigHelper.GetVauleToString("WriteNTCAddress1");
            this.WriteNTCAddress2 = ConfigHelper.GetVauleToString("WriteNTCAddress2");
            this.WriteNTCPowerOffAddress1 = ConfigHelper.GetVauleToString("WriteNTCPowerOffAddress1");
            this.WriteNTCPowerOffAddress2 = ConfigHelper.GetVauleToString("WriteNTCPowerOffAddress2");

            this.ScanStatus1 = new Status(App.GetString("Scan1 is not connected!"), MyBrushes.Red);
            this.ScanStatus2 = new Status(App.GetString("Scan2 is not connected!"), MyBrushes.Red);

            this.PLCStatus = new Status("PLC is not Connected!",MyBrushes.Red);

            this.IsDebug = ConfigHelper.GetValueToBoolean("IsPLCDebug");

            this.ReadAddressValue = "1,1,1,1";
        }

        #endregion
    }
}
